/**
 ******************************************************************************
 * @file           : linux_signal_simulator.c
 * @brief          : Linux信号仿真器示例
 ******************************************************************************
 * @attention
 *
 * 应用场景：在Linux PC上仿真和测试PSV算法
 * 功能：
 * - 生成模拟的周期信号（稳定信号 + 干扰信号）
 * - 使用PSV进行实时检测
 * - 输出检测结果和统计信息
 * - 可用于算法验证和参数调优
 *
 ******************************************************************************
 */

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include <math.h>
#include "../src/psv.h"

/* 仿真参数 */
#define STABLE_SIGNAL_FREQ      100     /* 稳定信号频率（Hz） */
#define NOISE_FREQ_MIN          50      /* 干扰信号最小频率（Hz） */
#define NOISE_FREQ_MAX          500     /* 干扰信号最大频率（Hz） */
#define SIMULATION_DURATION_S   30      /* 仿真时长（秒） */
#define SIGNAL_INTERVAL_MS      100     /* 信号间隔（毫秒） */

/* 信号类型 */
typedef enum
{
    SIGNAL_TYPE_STABLE = 0,     /* 稳定周期信号 */
    SIGNAL_TYPE_NOISE = 1       /* 随机干扰信号 */
} SignalType_e;

/* 统计数据 */
typedef struct
{
    uint32_t total_count;       /* 总信号数 */
    uint32_t stable_count;      /* 稳定信号数 */
    uint32_t noise_count;       /* 干扰信号数 */
    uint32_t psv_accept;        /* PSV接受数 */
    uint32_t psv_reject;        /* PSV拒绝数 */
    uint32_t true_positive;     /* 真阳性（正确接受） */
    uint32_t false_positive;    /* 假阳性（错误接受） */
    uint32_t true_negative;     /* 真阴性（正确拒绝） */
    uint32_t false_negative;    /* 假阴性（错误拒绝） */
} Statistics_t;

static Statistics_t s_stats = {0};

/**
 * @brief   生成稳定周期信号（带轻微波动）
 * @retval  频率（Hz）
 */
static uint32_t generate_stable_signal(void)
{
    /* 添加±2%的随机波动，模拟真实传感器 */
    float variation = ((rand() % 40) - 20) / 1000.0f;  /* -2% ~ +2% */
    uint32_t freq = (uint32_t)(STABLE_SIGNAL_FREQ * (1.0f + variation));
    return freq;
}

/**
 * @brief   生成随机干扰信号
 * @retval  频率（Hz）
 */
static uint32_t generate_noise_signal(void)
{
    /* 完全随机的频率 */
    uint32_t freq = NOISE_FREQ_MIN + (rand() % (NOISE_FREQ_MAX - NOISE_FREQ_MIN));
    return freq;
}

/**
 * @brief   更新统计信息
 * @param   signal_type: 实际信号类型
 * @param   psv_result: PSV检测结果
 */
static void update_statistics(SignalType_e signal_type, uint8_t psv_result)
{
    s_stats.total_count++;
    
    /* 统计信号类型 */
    if (signal_type == SIGNAL_TYPE_STABLE)
    {
        s_stats.stable_count++;
    }
    else
    {
        s_stats.noise_count++;
    }
    
    /* 统计PSV结果 */
    if (psv_result)
    {
        s_stats.psv_accept++;
    }
    else
    {
        s_stats.psv_reject++;
    }
    
    /* 统计检测准确性 */
    if (signal_type == SIGNAL_TYPE_STABLE && psv_result)
    {
        s_stats.true_positive++;   /* 稳定信号被正确接受 */
    }
    else if (signal_type == SIGNAL_TYPE_NOISE && psv_result)
    {
        s_stats.false_positive++;  /* 干扰信号被错误接受 */
    }
    else if (signal_type == SIGNAL_TYPE_NOISE && !psv_result)
    {
        s_stats.true_negative++;   /* 干扰信号被正确拒绝 */
    }
    else if (signal_type == SIGNAL_TYPE_STABLE && !psv_result)
    {
        s_stats.false_negative++;  /* 稳定信号被错误拒绝 */
    }
}

/**
 * @brief   打印统计信息
 */
static void print_statistics(void)
{
    printf("\n========================================\n");
    printf("          PSV检测统计报告\n");
    printf("========================================\n\n");
    
    printf("总信号数: %u\n", s_stats.total_count);
    printf("  - 稳定信号: %u (%.1f%%)\n", 
           s_stats.stable_count, 
           100.0f * s_stats.stable_count / s_stats.total_count);
    printf("  - 干扰信号: %u (%.1f%%)\n\n", 
           s_stats.noise_count, 
           100.0f * s_stats.noise_count / s_stats.total_count);
    
    printf("PSV检测结果:\n");
    printf("  - 接受: %u\n", s_stats.psv_accept);
    printf("  - 拒绝: %u\n\n", s_stats.psv_reject);
    
    printf("检测准确性:\n");
    printf("  - 真阳性（正确接受稳定信号）: %u\n", s_stats.true_positive);
    printf("  - 假阳性（错误接受干扰信号）: %u\n", s_stats.false_positive);
    printf("  - 真阴性（正确拒绝干扰信号）: %u\n", s_stats.true_negative);
    printf("  - 假阴性（错误拒绝稳定信号）: %u\n\n", s_stats.false_negative);
    
    /* 计算准确率 */
    if (s_stats.total_count > 0)
    {
        float accuracy = 100.0f * (s_stats.true_positive + s_stats.true_negative) / s_stats.total_count;
        float precision = (s_stats.psv_accept > 0) ? 
                         (100.0f * s_stats.true_positive / s_stats.psv_accept) : 0;
        float recall = (s_stats.stable_count > 0) ? 
                      (100.0f * s_stats.true_positive / s_stats.stable_count) : 0;
        
        printf("性能指标:\n");
        printf("  - 准确率 (Accuracy):  %.1f%%\n", accuracy);
        printf("  - 精确率 (Precision): %.1f%%\n", precision);
        printf("  - 召回率 (Recall):    %.1f%%\n", recall);
    }
    
    printf("\n========================================\n");
}

/**
 * @brief   主函数
 */
int main(int argc, char *argv[])
{
    printf("========================================\n");
    printf("  PSV周期信号验证器 - Linux仿真器\n");
    printf("========================================\n\n");
    
    /* 初始化随机数种子 */
    srand(time(NULL));
    
    /* 初始化PSV */
    psv_init();
    printf("✓ PSV模块已初始化\n\n");
    
    printf("仿真参数:\n");
    printf("  - 稳定信号频率: %d Hz (±2%% 波动)\n", STABLE_SIGNAL_FREQ);
    printf("  - 干扰信号范围: %d ~ %d Hz (随机)\n", NOISE_FREQ_MIN, NOISE_FREQ_MAX);
    printf("  - 仿真时长: %d 秒\n", SIMULATION_DURATION_S);
    printf("  - 信号间隔: %d 毫秒\n\n", SIGNAL_INTERVAL_MS);
    
    printf("开始仿真...\n");
    printf("格式: [序号] 类型 频率Hz → PSV结果 (统计信息)\n");
    printf("----------------------------------------\n");
    
    /* 仿真循环 */
    uint32_t loop_count = (SIMULATION_DURATION_S * 1000) / SIGNAL_INTERVAL_MS;
    
    for (uint32_t i = 0; i < loop_count; i++)
    {
        /* 交替生成稳定信号和干扰信号（模拟真实场景） */
        SignalType_e signal_type;
        uint32_t freq;
        
        /* 70%概率生成稳定信号，30%概率生成干扰 */
        if ((rand() % 100) < 70)
        {
            signal_type = SIGNAL_TYPE_STABLE;
            freq = generate_stable_signal();
        }
        else
        {
            signal_type = SIGNAL_TYPE_NOISE;
            freq = generate_noise_signal();
        }
        
        /* PSV检测 */
        uint8_t psv_result = psv_check(freq);
        
        /* 更新统计 */
        update_statistics(signal_type, psv_result);
        
        /* 打印实时信息（每10个打印一次） */
        if (i % 10 == 0)
        {
            printf("[%04u] %s %3uHz → %s (接受:%u 拒绝:%u)\n",
                   i + 1,
                   (signal_type == SIGNAL_TYPE_STABLE) ? "稳定" : "干扰",
                   freq,
                   psv_result ? "✓接受" : "✗拒绝",
                   s_stats.psv_accept,
                   s_stats.psv_reject);
        }
        
        /* 延时 */
        usleep(SIGNAL_INTERVAL_MS * 1000);
    }
    
    printf("----------------------------------------\n");
    printf("仿真完成！\n");
    
    /* 打印统计报告 */
    print_statistics();
    
    /* 获取PSV内部统计信息 */
    PSV_Statistics_t psv_stats;
    psv_get_statistics(&psv_stats);
    
    printf("\nPSV内部状态:\n");
    printf("  - 变异系数 (CV): %.3f\n", psv_stats.cv);
    printf("  - 平均周期: %.1f us\n", psv_stats.mean_period_us);
    printf("  - 标准差: %.1f us\n", psv_stats.std_dev_us);
    printf("  - 采样数量: %u\n", psv_stats.sample_count);
    printf("  - 信号锁定: %s\n", psv_stats.is_locked ? "是" : "否");
    
    printf("\n仿真结束。\n");
    
    return 0;
}

/**
 * 编译和运行说明:
 * 
 * 1. 编译：
 *    gcc linux_signal_simulator.c ../src/psv.c -I../src -lm -o psv_simulator
 * 
 * 2. 运行：
 *    ./psv_simulator
 * 
 * 3. 预期输出：
 *    - 实时显示信号检测过程
 *    - 最终显示统计报告
 *    - 准确率应 >90%
 * 
 * 4. 用途：
 *    - 验证PSV算法有效性
 *    - 调整参数（修改 psv_config.h）
 *    - 测试不同场景（修改仿真参数）
 */
